﻿using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Modbus.Device;
using ProductMonitor.Models;
using ProductMonitor.UserControls;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;

namespace ProductMonitor.ViewModels
{
    public partial class MonitorUCVM : ObservableObject
    {

        #region 日期
        public string TimeStr
        {
            get
            {
                return DateTime.Now.ToString(" HH:mm");

            }

        }

        public string TimeStrs
        {
            get
            {
                return DateTime.Now.ToString("yyyy-MM-dd ");

            }

        }

        public string TimeStrss
        {
            get
            {
                int dayOfWeek = (int)DateTime.Now.DayOfWeek;
                string[] dayOfWeekStr = new string[7] { "周日", "周一", "周二", "周三", "周四", "周五", "周六" };
                return dayOfWeekStr[dayOfWeek]; // Fix: Return the correct string from the array based on the day of the week.
            }
        }
        #endregion
        #region 机器数量 、产品数量、坏品数量
        private string _MachineCount = "0298";
        private string _ProductCount = "02981";
        private string _BadCount = "02981";

        /// <summary>


        public string MachineCount // 初始化机器数量为0
        {
            get { return _MachineCount; }
            set
            {

                OnPropertyChanged(nameof(MachineCount)); // 使用基类的 OnPropertyChanged 方法来通知属性更改


            }
        }

        public string ProductCount // 初始化机器数量为0
        {
            get { return _ProductCount; }
            set
            {

                OnPropertyChanged(nameof(ProductCount)); // 使用基类的 OnPropertyChanged 方法来通知属性更改

            }
        }
        public string BadCount // 初始化机器数量为0
        {
            get { return _BadCount; }
            set
            {

                OnPropertyChanged(nameof(BadCount)); // 使用基类的 OnPropertyChanged 方法来通知属性更改

            }
        }
        #endregion
        #region 环境监控数据
        private List<EnviromentModel> _EnvironmentList;

        public List<EnviromentModel> EnvironmentList
        {
            get { return _EnvironmentList; }
            set
            {
                _EnvironmentList = value;
                OnPropertyChanged(nameof(EnvironmentList)); // 使用基类的 OnPropertyChanged 方法来通知属性更改
            }
        }
        #endregion

        #region 报警属性
        private List<AlarmModel> _AlarmList;

        public List<AlarmModel> AlarmList
        {
            get { return _AlarmList; }
            set
            {
                _AlarmList = value;
                OnPropertyChanged(nameof(AlarmList)); // 使用基类的 OnPropertyChanged 方法来通知属性更改
            }
        }
        #endregion

        #region 设备属性
        private List<DeviceModel> _DeviceList;

        public List<DeviceModel> DeviceList
        {
            get { return _DeviceList; }
            set
            {
                _DeviceList = value;
                OnPropertyChanged(nameof(DeviceList)); // 使用基类的 OnPropertyChanged 方法来通知属性更改
            }
        }
        #endregion

        #region 雷达属性
        private List<ReaderModel> _RadarList;

        public List<ReaderModel> RadarList
        {
            get { return _RadarList; }
            set
            {
                _RadarList = value;
                OnPropertyChanged(nameof(RadarList)); // 使用基类
            }
        }
        #endregion

        #region 机台集合属性

        private ObservableCollection<MachineModel> _MachineList = new ObservableCollection<MachineModel>();

        public ObservableCollection<MachineModel> MachineList
        {
            get { return _MachineList; }
            set
            {
                _MachineList = value;
                OnPropertyChanged(nameof(MachineList)); // 使用基类
            }
        }




        #endregion

        #region 人力属性
        private List<StuffOutWporkModel> _StuffOutWporkList;

        public List<StuffOutWporkModel> StuffOutWporkList
        {
            get { return _StuffOutWporkList; }
            set
            {
                _StuffOutWporkList = value;
                OnPropertyChanged(nameof(StuffOutWporkList)); // 使用基类
            }
        }
        #endregion

        #region 车间属性
        private List<WorkShopModel> _WorkShopModel;

        public List<WorkShopModel> WorkShopMList
        {
            get { return _WorkShopModel; }
            set
            {
                _WorkShopModel = value;
                OnPropertyChanged(nameof(WorkShopMList)); // 使用基类
            }
        }
        #endregion
        #region 跳转事件
        // 定义一个事件，通知界面跳转
        public event Action ShowDetailRequested;

        // 定义命令
        public IRelayCommand ShowDetailCommand { get; }
        private void OnShowDetail()
        {
            // 触发事件，通知界面跳转
            ShowDetailRequested?.Invoke();
        }

        #endregion
        #region  初始化数据

        #region 筛选数据
        //添加一个原始机台数据列表，用于筛选
        private ObservableCollection<MachineModel> _AllMachineList = new ObservableCollection<MachineModel>();
        public ObservableCollection<MachineModel> AllMachineList
        {
            get => _AllMachineList;// 如果未初始化，则使用当前的 MachineList 初始化
            set
            {
                _AllMachineList = value;

            }
        }
        //修改 FillterCommand 方法，添加筛选功能
        public ObservableCollection<MachineModel> FilterMachineList
        {
            get => _MachineList;
            set
            {
                _MachineList = value;
                OnPropertyChanged(nameof(FilterMachineList)); // 使用基类的 OnPropertyChanged 方法来通知属性更改
            }
        }
        // 优化筛选机台数据命令
        [RelayCommand]
        private void FillterCommand(string status)
        {
            //根据状态筛选机台数据
            if (status == "全部")
            {
                MachineList = new ObservableCollection<MachineModel>(AllMachineList);
            }
            else
            {
                MachineList = new ObservableCollection<MachineModel>(AllMachineList.Where
                (m =>
                (status == "作业中" && m.Status.Contains("作业中")) ||
                m.Status == status
            ));// 筛选出状态为指定值的机台
            }
        }
        #endregion
        public MonitorUCVM()
        {


            //初始化跳转
            ShowDetailCommand = new RelayCommand(OnShowDetail);

            // 初始化机器数据
            MachineList = new ObservableCollection<MachineModel>
            {
                new MachineModel { MachineName = "注塑机", PlanCount = 15, FinishedCount = 8, OrderNo = "h20250604",Status="作业中" },
                new MachineModel { MachineName = "焊接机", PlanCount = 25, FinishedCount = 10, OrderNo = "h20254564",Status="作业中" },
                new MachineModel { MachineName = "组装线", PlanCount = 35, FinishedCount = 20, OrderNo = "h202504564",Status="作业中" },
                new MachineModel { MachineName = "测试设备", PlanCount = 45, FinishedCount = 36, OrderNo = "h20780604",Status="作业中" },
                new MachineModel { MachineName = "包装机", PlanCount = 55, FinishedCount = 50, OrderNo = "h202595604",Status="作业中" },
                new MachineModel { MachineName = "喷涂设备", PlanCount = 65, FinishedCount = 61, OrderNo = "h2040604",Status="作业中" },
                new MachineModel { MachineName = "质检设备", PlanCount = 75, FinishedCount = 74, OrderNo = "h20250604",Status="作业中" },
                new MachineModel { MachineName = "注塑机", PlanCount = 15, FinishedCount = 8, OrderNo = "h20250604",Status="等待" },
                new MachineModel { MachineName = "注塑机", PlanCount = 15, FinishedCount = 8, OrderNo = "h20250604",Status="等待" },
                new MachineModel { MachineName = "注塑机", PlanCount = 15, FinishedCount = 8, OrderNo = "h20250604",Status="等待" },
                new MachineModel { MachineName = "注塑机", PlanCount = 15, FinishedCount = 8, OrderNo = "h20250604",Status="等待" },
                new MachineModel { MachineName = "注塑机", PlanCount = 15, FinishedCount = 8, OrderNo = "h20250604",Status="等待" },
                new MachineModel { MachineName = "注塑机", PlanCount = 15, FinishedCount = 8, OrderNo = "h20250604",Status="等待" },
                new MachineModel { MachineName = "注塑机", PlanCount = 15, FinishedCount = 8, OrderNo = "h20250604",Status="等待" },
                new MachineModel { MachineName = "注塑机", PlanCount = 15, FinishedCount = 8, OrderNo = "h20250604",Status="作业中" },
                new MachineModel { MachineName = "注塑机", PlanCount = 15, FinishedCount = 8, OrderNo = "h20250604",Status="等待" },
                new MachineModel { MachineName = "注塑机", PlanCount = 15, FinishedCount = 8, OrderNo = "h20250604",Status="作业中" },
                new MachineModel { MachineName = "注塑机", PlanCount = 15, FinishedCount = 8, OrderNo = "h20250604",Status="故障" },
                new MachineModel { MachineName = "注塑机", PlanCount = 15, FinishedCount = 8, OrderNo = "h20250604",Status="等待" },
                new MachineModel { MachineName = "注塑机", PlanCount = 15, FinishedCount = 8, OrderNo = "h20250604",Status="作业中" },
                new MachineModel { MachineName = "注塑机", PlanCount = 15, FinishedCount = 8, OrderNo = "h20250604",Status="作业中" },
                new MachineModel { MachineName = "注塑机", PlanCount = 15, FinishedCount = 8, OrderNo = "h20250604",Status="作业中" },
                new MachineModel { MachineName = "注塑机", PlanCount = 15, FinishedCount = 8, OrderNo = "h20250604",Status="等待" },
                new MachineModel { MachineName = "注塑机", PlanCount = 15, FinishedCount = 8, OrderNo = "h20250604",Status="作业中" },
                new MachineModel { MachineName = "注塑机", PlanCount = 15, FinishedCount = 8, OrderNo = "h20250604",Status="作业中" },
                new MachineModel { MachineName = "注塑机", PlanCount = 15, FinishedCount = 8, OrderNo = "h20250604",Status="作业中" },
                new MachineModel { MachineName = "注塑机", PlanCount = 15, FinishedCount = 8, OrderNo = "h20250604",Status="故障" },
                new MachineModel { MachineName = "注塑机", PlanCount = 15, FinishedCount = 8, OrderNo = "h20250604",Status="作业中" },
                new MachineModel { MachineName = "注塑机", PlanCount = 15, FinishedCount = 8, OrderNo = "h20250604",Status="故障" },
                new MachineModel { MachineName = "注塑机", PlanCount = 15, FinishedCount = 8, OrderNo = "h20250604",Status="故障" },
                new MachineModel { MachineName = "注塑机", PlanCount = 15, FinishedCount = 8, OrderNo = "h20250604",Status="作业中" },
                new MachineModel { MachineName = "注塑机", PlanCount = 15, FinishedCount = 8, OrderNo = "h20250604",Status="作业中" },
                new MachineModel { MachineName = "注塑机", PlanCount = 15, FinishedCount = 8, OrderNo = "h20250604",Status="故障" },
                new MachineModel { MachineName = "注塑机", PlanCount = 15, FinishedCount = 8, OrderNo = "h20250604",Status="作业中" },
                new MachineModel { MachineName = "注塑机", PlanCount = 15, FinishedCount = 8, OrderNo = "h20250604",Status="故障" },
                new MachineModel { MachineName = "注塑机", PlanCount = 15, FinishedCount = 8, OrderNo = "h20250604",Status="作业中" },
            };
            AllMachineList = new ObservableCollection<MachineModel>(MachineList); // 初始化原始机台数据列表
            // 初始化环境监控数据
            EnvironmentList = new List<EnviromentModel>
            {
                new EnviromentModel { EnItemName = "温度", EnItemValue = "25°C" },
                new EnviromentModel { EnItemName = "湿度", EnItemValue = "60%" },
                new EnviromentModel { EnItemName = "气压", EnItemValue = "1013 hPa" },
                new EnviromentModel { EnItemName = "光照", EnItemValue = "123" },
                new EnviromentModel { EnItemName = "噪音", EnItemValue = "23" },
                new EnviromentModel { EnItemName = "氮气（PPM）", EnItemValue = "24" },
                new EnviromentModel { EnItemName = "硫化氢（PPM）", EnItemValue = "18" }
            };

            // 初始化报警数据
            AlarmList = new List<AlarmModel>
            {
                new AlarmModel { Num = "01", Msg = "过高",Time="2023-11-23",Duration=7 },
                new AlarmModel { Num = "01", Msg = "过高",Time="2023-11-23",Duration=7 },
                new AlarmModel { Num = "01", Msg = "过高",Time="2023-11-23",Duration=7 },
                new AlarmModel { Num = "01", Msg = "过高",Time="2023-11-23",Duration=7 },
                new AlarmModel { Num = "01", Msg = "过高",Time="2023-11-23",Duration=7 },
                new AlarmModel { Num = "01", Msg = "过高",Time="2023-11-23",Duration=7 },
                new AlarmModel { Num = "01", Msg = "过高",Time="2023-11-23",Duration=7 },
            };

            //初始化设备数据
            DeviceList = new List<DeviceModel>
            {
                new DeviceModel { DeItemName = "电压(V)", DeItemValue = "390" },
                new DeviceModel { DeItemName = "电流(A)", DeItemValue = "60.9" },
                new DeviceModel { DeItemName = "温度('C)", DeItemValue = "35" },
                new DeviceModel { DeItemName = "气压(Kpal)", DeItemValue = "0.4" },
                new DeviceModel { DeItemName = "转速(r/s)", DeItemValue = "9300" }
            };

            //初始化雷达数据
            RadarList = new List<ReaderModel>
            {
                new ReaderModel { ItemName = "排烟风机", Value = 90.5 },
                new ReaderModel { ItemName = "客梯", Value = 20.3 },
                new ReaderModel { ItemName = "供水机", Value = 50.6 },
                new ReaderModel { ItemName = "稳压设备", Value = 61.2 },
                new ReaderModel { ItemName = "喷淋水泵", Value = 69.3 }
            };

            //初始化人力数据
            StuffOutWporkList = new List<StuffOutWporkModel>
            {
                new StuffOutWporkModel { StuffName = "张三", Position = "操作员" ,OutWorkCount=800 },
                new StuffOutWporkModel { StuffName = "李机", Position = "技术员" ,OutWorkCount=105 },
                new StuffOutWporkModel { StuffName = "王机", Position = "站长" ,OutWorkCount=12 },
                new StuffOutWporkModel { StuffName = "宋机", Position = "副站长" ,OutWorkCount=80 },
                new StuffOutWporkModel { StuffName = "排烟风机", Position = "主管" ,OutWorkCount=5 },

            };

            //初始化车间数据
            WorkShopMList = new List<WorkShopModel>
            {
                new WorkShopModel { WorkShopName="注塑车间",WaitCount=51,WrongCount=10,WorkingCount=15,StopCount=6},
                new WorkShopModel { WorkShopName="测试车间",WaitCount=32,WrongCount=4,WorkingCount=10,StopCount=1},
                new WorkShopModel { WorkShopName="焊接车间",WaitCount=41,WrongCount=3,WorkingCount=54,StopCount=2},
                new WorkShopModel { WorkShopName="固晶车间",WaitCount=15,WrongCount=8,WorkingCount=15,StopCount=5},


            };

            //Task.Run(() =>
            //{
            //        using (SerialPort serialPort = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One))
            //        {
            //            serialPort.Open();
            //            IModbusSerialMaster master = ModbusSerialMaster.CreateRtu(serialPort);// 创建 Modbus 主站
            //          while (true)
            //          {
            //              //bool[] result =  master.ReadCoils(1, startAddr, readLen); // 读取线圈状态
            //              ushort vlaue = master.ReadHoldingRegisters(1, 0, 7)[0]; // 读取保持寄存器,从设备地址，寄存器起始地址，寄存器数量
            //            Application.Current.Dispatcher.Invoke(() =>//在WPF主线程（UI线程）上执行大括号 { ... } 内的代码
            //            {
            //                for (int i = 0; i < 10; i++)
            //                {
            //                    EnvironmentList[i].EnItemValue = vlaue.ToString(); // 更新环境监控数据
            //                }
            //            });
            //            Thread.Sleep(1000);
            //          }

            //        }
                
            //});

        }
        #endregion
        private void BtnReadColisStatus(object sender, RoutedEventArgs e)
        {
            #region 自己组装报文
            //ushort startAddress = 0; // 起始寄存器地址
            //ushort readLength = 8; // 读取寄存器的长度

            //List<byte> command = new List<byte>
            //{
            //    0x01, // 从站地址
            //    0x01, // 功能码：读取保持寄存器
            //    (byte)(startAddress >> 8), // 起始地址高8字节
            //    (byte)(startAddress & 0xFF), // 起始地址低8字节
            //    (byte)(readLength >> 8), // 读取寄存器高8字节
            //    (byte)(readLength & 0xFF) // 读取寄存器低8字节
            //};

            //command = CRC16(command); // 将命令转换为字节数组

            // 读取串口状态
            //try
            //{
            //    //从设备异步读取数据
            //    Task.Run(() =>//启动一个新的后台线程
            //    {
            //    //    //创建一个SerialPort对象，指定端口号为COM1，波特率为9600，无校验位，8位数据位，1位停止位。using保证用完后自动释放资源。
            //    //    using (SerialPort serialPort = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One))
            //    //    {
            //    //        serialPort.Open();//•	打开串口，准备进行数据通信。
            //    //        serialPort.Write(command.ToArray(), 0, command.Count); //•	通过串口发送命令，读取从站的保持寄存器数据。
            //    //        byte[] response = new byte[serialPort.BytesToRead]; //•	创建一个字节数组response，用于存储从设备返回的数据。
            //    //        serialPort.Read(response, 0, response.Length); //•	从串口读取数据，存储到response数组中。
            //    //        List<byte> respList = new List<byte>(response);//•	将读取到的字节数组转换为List<byte>类型，方便后续处理。
            //    //        respList.RemoveRange(0, 3); //•	移除前3个字节（从站地址、功能码和字节计数），只保留实际数据部分。
            //    //        respList.RemoveRange(respList.Count - 2, 2); //•	移除最后2个字节（CRC校验码），只保留实际数据部分。
            //    //        respList.Reverse(); //•	将剩余的字节顺序反转，以便正确解析数据。
            //    //        var respStrList = respList.Select(b => b.ToString()).ToList(); //•	将剩余的字节转换为字符串列表，便于显示或进一步处理。
            //    //        var result = " "; //•	创建一个空字符串result，用于存储最终的结果。
            //    //        foreach (var item in respStrList)
            //    //        {
            //    //            result += item.PadLeft(8,'0'); //•	遍历字符串列表，将每个字符串左侧填充0，使其长度为8，并拼接到result字符串中。
            //    //        }
            //    //        //字符串反转
            //    //        result = new string(result.ToArray().Reverse<char>().ToArray()); //•	将result字符串中的字符顺序反转，以便正确显示或处理。
            //    //        result = result.Length > readLength ? result.Substring(0, readLength) : result; //•	如果result字符串长度大于读取长度，则截取前readLength个字符，否则保持原样。
            //    //        // 进一步处理result字符串，比如记录日志或更新UI等
            //    //        Console.WriteLine($"Processed result: {result}"); //•	输出处理后的结果
            //    //        MessageBox.Show(result);
            //    //    }
            //    });
            //}
            //catch (Exception ex)
            //{
            //    // 异常处理
            //    Console.WriteLine($"Error reading serial port: {ex.Message}");
            //}
            #endregion
            #region 通过modbus组件读取报文
            // 使用 Modbus 组件读取数据
            ushort startAddr = 0; // 起始寄存器地址
            ushort readLen = 10; // 读取寄存器的长度
            Task.Run(() =>
            {
                try
                {
                    using (SerialPort serialPort = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One))
                    {
                        
                        serialPort.Open();
                        IModbusSerialMaster master = ModbusSerialMaster.CreateRtu(serialPort);// 创建 Modbus 主站
                        //bool[] result =  master.ReadCoils(1, startAddr, readLen); // 读取线圈状态
                        ushort vlaue = 97;
                       // master.WriteMultipleRegisters(1, startAddr, new ushort[] { 0x0001, 0x0002 }); // 写入多个寄存器
                        master.WriteSingleRegister(1, startAddr, vlaue); // 写入单个寄存器


                     
                    }
                }
                catch (Exception ex)
                {


                    Console.WriteLine($"Error occurred: {ex.Message}");
                    throw ;
                }

            });
        }
             #endregion

        private List<byte> CRC16(List<byte> command)
        {
           // CRC16 校验算法
            ushort crc = 0xFFFF; // 初始值
            foreach (byte b in command)
            {
                crc ^= b; // 异或操作
                for (int i = 0; i < 8; i++)
                {
                    if ((crc & 0x0001) != 0) // 检查最低位是否为1
                    {
                        crc >>= 1; // 右移一位
                        crc ^= 0xA001; // 异或多项式
                    }
                    else
                    {
                        crc >>= 1; // 右移一位
                    }
                }
            }
            command.Add((byte)(crc & 0xFF)); // 添加低字节
            command.Add((byte)(crc >> 8)); // 添加高字节
            return command; // 返回带有CRC校验的命令
        }
    }
}
